package com.xunyin.modules.balance.service.impl;

import com.alibaba.fastjson.JSONArray;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.xunyin.common.service.impl.BaseServiceImpl;
import com.xunyin.common.utils.QueryHelpPlus;
import com.xunyin.constant.Constants;
import com.xunyin.enums.StatusEnum;
import com.xunyin.modules.balance.domain.MtBalance;
import com.xunyin.modules.balance.service.MtBalanceService;
import com.xunyin.modules.balance.service.dto.BalanceDto;
import com.xunyin.modules.balance.service.dto.TBalanceQueryCriteria;
import com.xunyin.modules.balance.service.mapper.MtBalanceMapper;
import com.xunyin.modules.device.domain.TDevice;
import com.xunyin.modules.mtuserbalance.domain.MtUserBalance;
import com.xunyin.modules.mtuserbalance.service.MtUserBalanceService;
import com.xunyin.modules.user.domain.YxUser;
import com.xunyin.modules.user.service.YxUserService;
import com.xunyin.modules.weixin.service.WeixinService;
import com.xunyin.pagination.PaginationRequest;
import com.xunyin.pagination.PaginationResponse;
import com.xunyin.utils.StringUtil;
import com.xunyin.utils.StringUtils;
import com.xunyin.web.ResponseObject;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.PageImpl;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.*;

/**
 * 余额管理业务实现类
 * <p>
 * Created by xunyinyunshang <3594419785@qq.com>
 * CopyRight 讯音云商 https://www.tonetn.com
 */
@Service
@RequiredArgsConstructor
@Slf4j
//@RequiredArgsConstructor(onConstructor = @__(@Autowired))
@Transactional(propagation = Propagation.SUPPORTS, readOnly = true, rollbackFor = Exception.class)
public class MtBalanceServiceImpl extends BaseServiceImpl<MtBalanceMapper, MtBalance> implements MtBalanceService {

    @Autowired
    private MtBalanceMapper mtBalanceMapper;

/*    @Autowired
    private SysXbuserService sysXbuserService;*/

    @Autowired
    private YxUserService userService;

    @Autowired
    private WeixinService weixinService;

    @Autowired
    private MtUserBalanceService mtUserBalanceService;

/*    @Resource
    private MtUserMapper mtUserMapper;

    @Resource
    private WeixinService weixinService;

    @Resource
    private MemberService memberService;*/


    @Override
    public PaginationResponse<BalanceDto> queryBalanceListByPagination(PaginationRequest paginationRequest) {
        Page<MtBalance> pageHelper = PageHelper.startPage(paginationRequest.getCurrentPage(), paginationRequest.getPageSize());
        LambdaQueryWrapper<MtBalance> lambdaQueryWrapper = Wrappers.lambdaQuery();
        lambdaQueryWrapper.ne(MtBalance::getStatus, StatusEnum.DISABLE.getKey());

        String description = paginationRequest.getSearchParams().get("description") == null ? "" : paginationRequest.getSearchParams().get("description").toString();
        if (StringUtils.isNotBlank(description)) {
            lambdaQueryWrapper.like(MtBalance::getDescription, description);
        }
        String status = paginationRequest.getSearchParams().get("status") == null ? "" : paginationRequest.getSearchParams().get("status").toString();
        if (StringUtils.isNotBlank(status)) {
            lambdaQueryWrapper.eq(MtBalance::getStatus, status);
        }
        String userId = paginationRequest.getSearchParams().get("userId") == null ? "" : paginationRequest.getSearchParams().get("userId").toString();
        if (StringUtils.isNotBlank(userId)) {
            lambdaQueryWrapper.eq(MtBalance::getUserId, userId);
        }
        String orderSn = paginationRequest.getSearchParams().get("orderSn") == null ? "" : paginationRequest.getSearchParams().get("orderSn").toString();
        if (StringUtils.isNotBlank(orderSn)) {
            lambdaQueryWrapper.eq(MtBalance::getOrderSn, orderSn);
        }
        String mobile = paginationRequest.getSearchParams().get("mobile") == null ? "" : paginationRequest.getSearchParams().get("mobile").toString();
        if (StringUtils.isNotBlank(mobile)) {
            lambdaQueryWrapper.like(MtBalance::getMobile, mobile);
        }
        String storeId = paginationRequest.getSearchParams().get("storeId") == null ? "" : paginationRequest.getSearchParams().get("storeId").toString();
        if (StringUtils.isNotBlank(storeId)) {
            lambdaQueryWrapper.eq(MtBalance::getStoreId, storeId);
        }
        String storeIdList = paginationRequest.getSearchParams().get("storeIdList") == null ? "" : paginationRequest.getSearchParams().get("storeIdList").toString();
        if (StringUtils.isNotBlank(storeIdList)) {
            lambdaQueryWrapper.in(MtBalance::getStoreId, JSONArray.parseArray(storeIdList, Integer.class));
        }

        lambdaQueryWrapper.orderByDesc(MtBalance::getId);

        List<MtBalance> balanceList = mtBalanceMapper.selectList(lambdaQueryWrapper);

        List<BalanceDto> dataList = new ArrayList<>();
        for (MtBalance mtBalance : balanceList) {
            //MtUser userInfo = memberService.queryMemberById(mtBalance.getUserId());
            //SysXbuser userInfo = sysXbuserService.getById(mtBalance.getUserId());
            YxUser userInfo = userService.getById(mtBalance.getUserId().longValue());
            BalanceDto item = new BalanceDto();
            item.setId(mtBalance.getId());
            item.setAmount(mtBalance.getAmount());
            item.setGiveAmount(mtBalance.getGiveAmount());
            item.setDescription(mtBalance.getDescription());
            item.setCreateTime(mtBalance.getCreateTime());
            item.setUpdateTime(mtBalance.getUpdateTime());
            item.setUserId(mtBalance.getUserId());
            item.setUserInfo(userInfo);
            item.setOrderSn(mtBalance.getOrderSn());
            item.setStatus(mtBalance.getStatus());
            item.setOperator(mtBalance.getOperator());
            dataList.add(item);
        }

        PageRequest pageRequest = PageRequest.of(paginationRequest.getCurrentPage(), paginationRequest.getPageSize());
        PageImpl pageImpl = new PageImpl(dataList, pageRequest, pageHelper.getTotal());
        PaginationResponse<BalanceDto> paginationResponse = new PaginationResponse(pageImpl, BalanceDto.class);
        paginationResponse.setTotalPages(pageHelper.getPages());
        paginationResponse.setTotalElements(pageHelper.getTotal());
        paginationResponse.setContent(dataList);

        return paginationResponse;
    }

    @Override
    //@Cacheable
    public Map<String, Object> queryAll(TBalanceQueryCriteria criteria, Pageable pageable) {
        getPage(pageable);
        PageInfo<MtBalance> page = new PageInfo<>(queryAll(criteria));
        Map<String, Object> map = new LinkedHashMap<>(2);
        map.put("content", page.getList());
        map.put("totalElements", page.getTotal());
        return map;
    }

    @Override
    //@Cacheable
    public List<MtBalance> queryAll(TBalanceQueryCriteria criteria) {
        return baseMapper.selectList(QueryHelpPlus.getPredicate(TDevice.class, criteria));
    }

    /**
     * 会员余额变动,添加余额记录
     *
     * @param mtBalance
     */
    @Override
    @Transactional
    //@OperationServiceLog(description = "会员余额变动")
    public boolean addBalance(MtBalance mtBalance) {

        if (mtBalance.getUserId() < 0) {
            return false;
        }
        mtBalance.setStatus(StatusEnum.ENABLED.getKey());
        mtBalance.setCreateTime(new Date());
        mtBalance.setUpdateTime(new Date());

        //MtUser mtUser = mtUserMapper.selectById(tBalance.getUserId());
        //SysXbuser mtUser = sysXbuserService.getById(mtBalance.getUserId());
        YxUser user = userService.getById(mtBalance.getUserId().longValue());
        mtBalance.setMobile(user.getPhone());
        // 如果是门店充值，则更新到对应的用户门店余额表中
        if (mtBalance.getStoreId() > 0) {

            Map<String, Object> param = new HashMap<String, Object>();
            param.put("storeId", mtBalance.getStoreId());
            param.put("userId", mtBalance.getUserId());
            List<MtUserBalance> dataList = mtUserBalanceService.queryMtUserBalanceByParams(param);
            MtUserBalance mtUserBalance = dataList.get(0);
            BigDecimal newAmount = mtUserBalance.getUserBalance().add(mtBalance.getAmount());
            newAmount = newAmount.add(mtBalance.getGiveAmount());
            mtUserBalance.setUserBalance(newAmount);
            mtUserBalanceService.updateById(mtUserBalance);

        // 如果是平台充值，直接更新到用户表的余额中
        } else {

            BigDecimal newAmount = user.getNowMoney().add(mtBalance.getAmount());
            if (newAmount.compareTo(new BigDecimal("0")) < 0) {
                return false;
            }
            newAmount = newAmount.add(mtBalance.getGiveAmount());
            user.setNowMoney(newAmount);
            //mtUser.setBalance(newAmount);
            userService.updateById(user);

        }


        //sysXbuserService.updateById(mtUser);
        //tBalance.setMobile(mtUser.getMobile());
        //mtBalance.setMobile(mtUser.getUserAccount());
        mtBalanceMapper.insert(mtBalance);

        // 发送小程序订阅消息
/*      Date nowTime = new Date();
        Date sendTime = new Date(nowTime.getTime() + 60000);
        Map<String, Object> params = new HashMap<>();
        String dateTime = DateUtilV.formatDate(Calendar.getInstance().getTime(), "yyyy-MM-dd HH:mm");
        params.put("amount", tBalance.getAmount());
        params.put("time", dateTime);
        params.put("tips", "您的余额发生了变动，请留意~");
        weixinService.sendSubscribeMessage(tBalance.getUserId(), mtUser.getOpenId(), WxMessageEnum.BALANCE_CHANGE.getKey(), "pages/user/index", params, sendTime);*/

        return true;
    }

    /**
     * 获取订单余额记录
     *
     * @param orderSn
     * @return
     */
    @Override
    public List<MtBalance> getBalanceListByOrderSn(String orderSn) {
        return mtBalanceMapper.getBalanceListByOrderSn(orderSn);
    }

    /**
     * 获取用户充值列表
     *
     * @param paramMap
     */
    @Override
    @Transactional
    public ResponseObject getMyBalanceList(Map<String, Object> paramMap) {

        Integer pageNumber = paramMap.get("pageNumber") == null ? Constants.PAGE_NUMBER : Integer.parseInt(paramMap.get("pageNumber").toString());
        Integer pageSize = paramMap.get("pageSize") == null ? Constants.PAGE_SIZE : Integer.parseInt(paramMap.get("pageSize").toString());
        String userId = paramMap.get("userId") == null ? "" : paramMap.get("userId").toString();
        String status = paramMap.get("status") == null ? "" : paramMap.get("status").toString();
        String mobile = paramMap.get("mobile") == null ? "" : paramMap.get("mobile").toString();
        String storeId = paramMap.get("storeId") == null ? "" : paramMap.get("storeId").toString();

        Page<MtBalance> pageHelper = PageHelper.startPage(pageNumber, pageSize);
        LambdaQueryWrapper<MtBalance> lambdaQueryWrapper = Wrappers.lambdaQuery();
        //lambdaQueryWrapper.ne(MtBalance::getStatus, StatusEnum.DISABLE.getKey());

        if (StringUtil.isNotEmpty(status)) {
            lambdaQueryWrapper.eq(MtBalance::getStatus, status);
        }
        if (StringUtil.isNotEmpty(userId)) {
            lambdaQueryWrapper.eq(MtBalance::getUserId, userId);
        }
        if (StringUtil.isNotEmpty(mobile)) {
            lambdaQueryWrapper.eq(MtBalance::getMobile, mobile);
        }

        if (StringUtil.isNotEmpty(storeId)) {
            lambdaQueryWrapper.eq(MtBalance::getStoreId, storeId);
        }

        lambdaQueryWrapper.orderByDesc(MtBalance::getId);

        List<MtBalance> userBalanceList = mtBalanceMapper.selectList(lambdaQueryWrapper);

        PageRequest pageRequest = PageRequest.of(pageNumber, pageSize);
        PageImpl pageImpl = new PageImpl(userBalanceList, pageRequest, pageHelper.getTotal());
        PaginationResponse<MtBalance> paginationResponse = new PaginationResponse(pageImpl, MtBalance.class);
        paginationResponse.setTotalPages(pageHelper.getPages());
        paginationResponse.setTotalElements(pageHelper.getTotal());
        paginationResponse.setContent(userBalanceList);

        return new ResponseObject(200, "查询成功", paginationResponse);
    }
}
